package jmine.tec.database.query;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;

import org.hibernate.jdbc.Work;

/**
 * Loader de colunas que compõe a chave primária de uma tabela.
 * 
 * @author lundberg
 */
public class PrimaryKeyColumnsLoader implements Callable<List<String>> {

    private final Database database;

    private final Table table;

    /**
     * Construtor
     * 
     * @param database database
     * @param table table
     */
    public PrimaryKeyColumnsLoader(Database database, Table table) {
        this.database = database;
        this.table = table;
    }

    /**
     * {@inheritDoc}
     */
    public List<String> call() {
        final Set<String> columns = new LinkedHashSet<String>();
        this.database.doWork(new Work() {
            public void execute(Connection connection) throws SQLException {
                String schema = PrimaryKeyColumnsLoader.this.database.getSchema();
                String tableName = PrimaryKeyColumnsLoader.this.table.getName();
                this.load(connection, schema, tableName);
                if (schema != null) {
                    this.load(connection, schema.toUpperCase(), tableName);
                }
            }

            /**
             * @param columns columns
             * @param connection connection
             * @param schema schema
             * @param tableName tableName
             * @throws SQLException SQLException
             */
            private void load(Connection connection, String schema, String tableName) throws SQLException {
                ResultSet rs = null;
                try {
                    rs = connection.getMetaData().getPrimaryKeys(null, schema, tableName);
                    while (rs.next()) {
                        columns.add(rs.getString("COLUMN_NAME"));
                    }
                } finally {
                    DatabaseUtil.closeQuietly(rs);
                }
            }
        });
        return new ArrayList<String>(columns);
    }
}
